/*
 * AccountsPanel.java
 *
 *  
 */
package org.msb.finance.app;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.text.NumberFormat;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;

import org.msb.finance.data.Account;
import org.msb.finance.data.Cabinet;
import org.msb.finance.models.AccountTableModel;

/**
 * 
 * 
 * @author boudream
 * 
 */
@SuppressWarnings("serial")
public class AccountsPanel extends JPanel implements TableModelListener, ActionListener {

	/**
	 * 
	 */
	private JTable accountsTable;

	/**
	 * 
	 */
	private JLabel balanceLabel;

	/**
	 * 
	 */
	private JPopupMenu popup;

	/*
	 * The Cabinet whose accounts are being displayed.
	 */
	private Cabinet cabinet;

	/*
	 * 
	 */
	private FinanceFrame frame;

	/**
	 * 
	 * @param frame
	 * @param cabinet
	 */
	public AccountsPanel(FinanceFrame frame, Cabinet cabinet) {
		super(new GridBagLayout(), true);

		this.frame = frame;

		panelInit();
	}

	/**
	 * 
	 */
	protected void panelInit() {
		setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		JLabel label = new JLabel(FinanceApp.getMessageResources().getString("tab.accounts.heading.caption")); //$NON-NLS-1$
		label.setFont(label.getFont().deriveFont(14f));

		add(label, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
				new Insets(0, 0, 5, 0), 0, 0));

		add(new JSeparator(), new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setViewportView(createAccountsTable());

		add(scrollPane, new GridBagConstraints(0, 2, 1, 1, 0.0, 1.0, GridBagConstraints.CENTER,
				GridBagConstraints.BOTH, new Insets(5, 0, 0, 0), 0, 0));

		this.balanceLabel = new JLabel();
		updateBalanceLabel();

		add(this.balanceLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST,
				GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
	}

	/**
	 * 
	 * @return
	 */
	private JPanel createAccountsTable() {
		JPanel panel = new JPanel(new BorderLayout());

		AccountTableModel model = this.frame.createAccountTableModel();
		model.addTableModelListener(this);
		this.accountsTable = new JTable(model);
		this.accountsTable.setDefaultRenderer(BigDecimal.class, new DefaultTableCellRenderer() {
			private NumberFormat format = NumberFormat.getNumberInstance();

			{
				this.format.setMaximumFractionDigits(2);
				this.format.setGroupingUsed(true);
				this.format.setMinimumFractionDigits(2);
				this.format.setMinimumIntegerDigits(1);

				setHorizontalAlignment(SwingConstants.RIGHT);
			}

			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
					boolean hasFocus, int row, int column) {
				JLabel l = (JLabel) super.getTableCellRendererComponent(table, null == value ? value : this.format
						.format(value), isSelected, hasFocus, row, column);

				return l;
			}
		});
		this.accountsTable.setShowGrid(false);
		this.accountsTable.setComponentPopupMenu(createTablePopupMenu());
		this.accountsTable.addMouseListener(new MouseAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
			 */
			@Override
			public void mouseClicked(MouseEvent e) {
				if (2 == e.getClickCount()) {
					// open account register.
				}
			}

		});

		panel.add(this.accountsTable, BorderLayout.CENTER);

		return panel;
	}

	/*
	 * 
	 */
	private JPopupMenu createTablePopupMenu() {
		this.popup = new JPopupMenu();

		this.popup.add(new JMenuItem("Open Register...")); //$NON-NLS-1$
		this.popup.add(new JMenuItem("Delete")); //$NON-NLS-1$
		JMenuItem menuItem = new JMenuItem("Change Account Details..."); //$NON-NLS-1$
		menuItem.setActionCommand("editaccountdetails"); //$NON-NLS-1$
		menuItem.addActionListener(this);
		this.popup.add(menuItem);
		this.popup.addSeparator();
		this.popup.add(new JMenuItem("New Account...")); //$NON-NLS-1$

		return this.popup;
	}

	/**
	 * 
	 * @param cabinet
	 */
	public void setCabinet(Cabinet cabinet) {
		this.cabinet = cabinet;
	}

	/*
	 * 
	 */
	private void updateBalanceLabel() {
		BigDecimal balance = null == this.cabinet ? new BigDecimal(0.0) : this.cabinet.getBalance();

		this.balanceLabel.setText(MessageFormat.format(FinanceApp.getMessageResources().getString(
				"tab.accounts.balance.caption"), balance)); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
	 */
	public void tableChanged(TableModelEvent e) {
		updateBalanceLabel();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();

		if (command.equals("editaccountdetails")) { //$NON-NLS-1$
			AccountTableModel model = (AccountTableModel) this.accountsTable.getModel();
			Account account = model.getAccountAt(this.accountsTable.getSelectedRows()[0]);

			AccountDetailsDialog dialog = AccountDetailsDialog.createDialog(this.frame, account);
			dialog.editAccount(account);
		}
	}
}
